package com.bytes32.parsing;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility class that tries to convert a string into some form 
 * of writable depending on the available parsers
 * @author murariuf
 *
 */
public final class TypeEvaluator {
	
	/*
	 * Logger
	 */
	private static final Logger LOG = LoggerFactory.getLogger(TypeEvaluator.class);
	
	/**
	 * Attempts to output the best match for each value
	 * based on the parsers in the list
	 * @param values
	 *  the allocated values to evaluate the feature against
	 * @param parsers
	 *  the parsers
	 * @param count
	 *  FIXME: remove me
	 *  the number of successful parse operations
	 *  before the attribute is assigned a type
	 *  and a feature is returned
	 * @return
	 *  {@link Parser} that successfully recognized the most values
	 * @throws ParsingException 
	 */
	@SuppressWarnings("rawtypes")
	public static Parser parseAndReset(Object[] values, List<Parser> parsers, int count) throws ParsingException{
		if (parsers == null || parsers.size() == 0)
			throw new IllegalArgumentException(" No parsers available ");
		/* we assign a weight to each parser*/
		for (Object value : values){
			try {
				executeParsers(value, parsers);
			} catch (ParsingException e) {
				/* no problems */
			} 
		}
		/* done counting get the most successful parser
		 * TODO: could improve things here but for now we stick with simple */
		int max = Integer.MIN_VALUE;
		Parser winner = null;
		for ( int i = 0; i <parsers.size(); i++){
			Parser next = parsers.get(i);
			if (next.getWeight() > max) {
				winner = next;
				max = next.getWeight();
			}
			next.reset();
		}
		return winner;
	}
	
	/*
	 * Runs every parser on the value
	 * if we have a number representation we 
	 * consider 
	 * then the weight is incremented
	 */
	private static void  executeParsers(Object value, Collection<Parser> parsers) throws ParsingException{
		for (Parser parser : parsers){
			try {
				try {
					parser.intoNumber(value);
					parser.incrementWeight();
				} catch ( ParsingException e) {
					/* no problem */
				} 
				
				try {
					parser.intoText(value);
					parser.incrementWeight();
				} catch (ParsingException e1) {
					/* no problem*/
				}
			} catch (RuntimeException e) {
				/* bad dog */
				LOG.error(" Unable to execute parser: "+parser+" on value: "+value,e);
			} 
		}
	}
	
	
}
